﻿import mx.events.EventDispatcher;
import mx.utils.Delegate;

import com.mixmedia.mx.Event;
import com.mixmedia.net.LoadXML;
import com.mixmedia.net.URLLoader;

/**
 * @author colin
 * @description the Abstract class of List
 * @sample
 * 
 * @SetLocalDataProvider
 * IList.dataProvider = array;
 * 
 * @SetRemoteDataProvider
 * IList.remoteDataProviderURL;
 * IList.getDataFromRemote();
 * 
 */
class com.mixmedia.control.IList extends MovieClip{
	private var _dp : Array;
	public var cellRenderer: String;
	public var rowCount : Number;
	private var _selectedIndex : Number;
	private var _scroll : Number=0;
	private var _dpURL : String;
	private var remoteDataResolver : Function;

	public function IList(){
		EventDispatcher.initialize(this);
		addEventListener(Event.INIT,Delegate.create(this,redraw));
		//addEventListener(Event.SCROLL,Delegate.create(this,redraw));
	}

	public function addItem(itemObj:Object):Number{
		return _dp.push(itemObj);
	}
	
	public function addItemAt(index:Number,itemObj:Object):Number{
		_dp.splice(index,0,itemObj);
		return length;
	}
	
	public function getItemAt(index:Number){
		return _dp[index];
	}

	public function removeAll(){
		_dp = new Array();
	}
	
	public function removeItemAt(index:Number):Object{
		var item = _dp[index];
		_dp.splice(index,1);
		return item;
	}
	
	public function replaceItemAt(index:Number,itemObj:Object){
		_dp[index] = itemObj;
	}
	
	public function sortItems(compareFunction:Function){
		_dp.sort(compareFunction);
	}
	
	public function sortItemsBy(fieldName:String,order:Number){
		_dp.sortOn(fieldName,order);
	}

// properties
/**
 * @param dp is collection of object
 */
	public function set dataProvider(dp:Array):Void{
		_dp = dp;
		dispatchEvent(new Event(this,Event.INIT,{value:dp}));
	};

	public function get dataProvider():Array{
		return _dp;
	};

/**
 * @return length of the dataProvider
 */
	public function get length():Number{
		return dataProvider.length;
	};

/**
 * @param The index of a selection in a single-selection list;
 */
	public function get selectedIndex():Number{
		return _selectedIndex;
	};

	public function set selectedIndex(index:Number):Void{
		_selectedIndex = index;
		dispatchEvent(new Event(this,Event.CHANGE,{value:_selectedIndex}));
	};

/**
 * @return selected Item. read only
 */
 	public function get selectedItem(){
 		return dataProvider[selectedIndex];
 	}

/**
 * @param The topmost visible item of the list;
 */

	public function set scroll(index:Number):Void{
		var lastScroll:Number = _scroll;
		_scroll = index;
		if(_scroll<0)_scroll=0;
		if(_scroll>=length-1)_scroll=length-1;
		dispatchEvent(new Event(this,Event.SCROLL,{direction:'verticle',position:_scroll,lastPosition:lastScroll}));
	};

	public function get scroll():Number{
		return _scroll;
	};


/**
 * @param URL to load the xml
 */

	public function set remoteDataProviderURL(url:String):Void{
		_dpURL = url;
	}

	public function get remoteDataProviderURL():String{
		return _dpURL;
	}

// methods
	public function getDataFromRemote(){
		var remoteData:URLLoader = new URLLoader(new LoadXML());
		remoteData.addEventListener(Event.READY,Delegate.create(this,onRemoteDataReady));
		remoteData.load(remoteDataProviderURL);
		dispatchEvent(new Event(this,Event.OPEN));
	}

// virtual methods
	public function setListHeader(headerObject):Void{};

//private methods
//the event handler of remote data request;
	private function onRemoteDataReady(evt) : Void {
		var xData:XML = evt.target;
		dataProvider = remoteDataResolver(xData);
		dispatchEvent(new Event(this,Event.READY,{value:xData}));
	}

	private function redraw(evt):Void{
	}

//Event Dispatchers
	public function addEventListener(event:String, handler):Void{}
	private function dispatchEvent(eventObj:Object):Void{}
	public function removeEventListener(event:String, handler):Void{}
}